package com.wstuo.common.config.category.service;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.wstuo.common.config.category.dao.ICICategoryDAO;
import com.wstuo.common.config.category.dto.CategoryDTO;
import com.wstuo.common.config.category.dto.CategoryTreeViewDTO;
import com.wstuo.common.config.category.entity.CICategory;
import com.wstuo.common.config.category.entity.Category;
import com.wstuo.common.exception.ApplicationException;
import com.wstuo.common.file.csv.CSVReader;
import com.wstuo.common.file.csv.CSVWriter;
import com.wstuo.common.security.dao.IFunctionDAO;
import com.wstuo.common.security.dao.IOperationDAO;
import com.wstuo.common.security.dao.IRoleDAO;
import com.wstuo.common.security.dto.OperationDTO;
import com.wstuo.common.security.entity.Function;
import com.wstuo.common.security.entity.Operation;
import com.wstuo.common.security.entity.Resource;
import com.wstuo.common.security.entity.Role;
import com.wstuo.common.security.service.IOperationService;
import com.wstuo.common.security.service.IRoleService;
import com.wstuo.common.security.service.IUserInfoService;
import com.wstuo.common.security.utils.AppContext;
import com.wstuo.common.security.utils.FileEncodeUtils;
import com.wstuo.common.security.utils.LanguageContent;
import com.wstuo.common.util.StringUtils;

/**
 * ConfigurationItemsService Bean 2010.9.13
 * 
 * @author spring
 * 
 */
public class CICategoryService implements ICICategoryService {
	public static final String DEFAULT_SEPARATOR = "-";
	
	final static Logger LOGGER = Logger.getLogger(CICategoryService.class);
	@Autowired
	private ICICategoryDAO cicategoryDAO;
	@Autowired
	private IOperationDAO operationDAO;
	@Autowired
	private IOperationService operationService;
	@Autowired
	private IUserInfoService userInfoService;
	@Autowired
	private IRoleDAO roleDAO;
	@Autowired
	private IFunctionDAO functionDAO;
	@Autowired
	private AppContext appctx;

	/**
	 * 
	 * Check all CICategoryTree
	 * 
	 * @param categoryRoot
	 * @param isAll
	 * @param userName
	 * @param parentEventId
	 * @return List<CategoryTreeViewDTO>
	 */
	@Transactional
	public List<CategoryTreeViewDTO> findCICategoryTreeDtos(
			String categoryRoot, boolean isAll, String userName,
			Long parentEventId) {
		List<CategoryTreeViewDTO> dtos = new ArrayList<CategoryTreeViewDTO>();

		List<CICategory> entities = cicategoryDAO
				.findConfigurationItems(categoryRoot);

		Long[] categoryNos = null;
		if (userName != null)
			categoryNos = userInfoService.findCategoryNosByLoginName(userName,
					"CONFIGUREITEMCATEGORY_RES");

		for (CICategory entity : entities) {
			CategoryTreeViewDTO dto = new CategoryTreeViewDTO();
			entity2dto(entity, dto, isAll, categoryNos, true);
			dtos.add(dto);

		}
		return dtos;
	}

	/**
	 * view configuration category tree
	 */
	@Transactional
	public CategoryTreeViewDTO findCICategoryTree(String categoryRoot,
			boolean isAll, String userName, boolean isSimpleDto,
			Long parentEventId) {
		CICategory entity = cicategoryDAO.findConfigureItemTree(categoryRoot);
		if (entity != null && !StringUtils.hasText(entity.getPath())) {
			this.updateAllCategoryPath();
		}
		CategoryTreeViewDTO dto = new CategoryTreeViewDTO();
		Long[] categoryNos = null;
		if (!isAll && userName != null)
			categoryNos = userInfoService.findCategoryNosByLoginName(userName,
					"CONFIGUREITEMCATEGORY_RES");
		entity2dto(entity, dto, isAll, categoryNos, isSimpleDto);
		return dto;
	}

	/**
	 * view configuration category list
	 */
	@Transactional
	public List<CategoryTreeViewDTO> findCICategoryTreeSub(String categoryRoot,
			boolean isAll, String userName, boolean isSimpleDto,
			Long parentEventId) {

		CICategory entity = cicategoryDAO
				.findConfigureItemTreeByParentEventId(parentEventId);
		List<CategoryTreeViewDTO> dtoList = new ArrayList<CategoryTreeViewDTO>();
		Long[] categoryNos = null;
		if (!isAll && userName != null)
			categoryNos = userInfoService.findCategoryNosByLoginName(userName,
					"CONFIGUREITEMCATEGORY_RES");
		entity2dtoSub(entity, dtoList, isAll, categoryNos,
				isSimpleDto);
		return dtoList;
	}

	/**
	 * Find CICategory
	 * 
	 * @param categoryId
	 */
	@Transactional
	public CategoryDTO findCICategoryById(Long categoryId) {
		CICategory entity = cicategoryDAO.findById(categoryId);

		CategoryDTO dtos = new CategoryDTO();
		dtos.setCategoryType(entity.getCategoryType());
		dtos.setCategoryRoot(entity.getCategoryRoot());
		dtos.setCategoryCodeRule(entity.getCategoryCodeRule());
		dtos.setDescription(entity.getDescription());
		CategoryDTO.entity2dto(entity, dtos);
		// add mars
		if (entity.getParent() != null) {
			dtos.setParentNo(entity.getParent().getCno());
		}
		if (entity.getChildren() != null) {
			dtos.setChildren(entity.getChildren());
		}
		return dtos;
	}

	/**
	 * 判断分类是否存在
	 * 
	 * @param dto
	 * @return
	 */
	public boolean isCategoryExisted(CategoryDTO dto) {
	    if (dto.getParentNo() == null) {
	        Category category = cicategoryDAO.findById(dto.getCno());
	        if(category.getParent()!=null){
	        	 dto.setParentNo(category.getParent().getCno());
	        }
	    }
	    if (dto.getCname() == null) {
	        Category category = cicategoryDAO.findById(dto.getCno());
	        dto.setCname(category.getCname());
	    }
		return cicategoryDAO.isCategoryExisted(dto);
	}
	
	/**
	 * 判断编辑时分类是否存在
	 * @param dto
	 * @return
	 */
	public boolean isCategoryExistdOnEdit(CategoryDTO dto) {
	    boolean flag = true;
	    Category category = cicategoryDAO.findById(dto.getCno());
	    if (dto.getCname()!=null&&category!=null&&dto.getCname().equals(category.getCname())) {
	        flag = false;
	    } else {
	        flag = this.isCategoryExisted(dto);
	    }
        return flag;
	}

	/**
	 * Save CICategory
	 * 
	 * @param dto
	 */
	@Transactional
	public void saveCICategory(CategoryDTO dto) {
		CICategory entity = new CICategory();
		CategoryDTO.dto2entity(dto, entity);
		if (dto.getParentNo() != null) {
			CICategory parent = cicategoryDAO.findById(dto.getParentNo());
			// add mars---start
			entity.setParent(parent);
		}
		cicategoryDAO.save(entity);
		if (entity.getParent() != null) {
			entity.setPath(entity.getParent().getPath() + entity.getCno() + "/");
			entity.setPathAlias((entity.getParent().getPathAlias() + entity.getCname() + "/"));
		} else {
			entity.setPath(entity.getCno() + "/");
			entity.setPathAlias(entity.getCname() + "/");
		}
		// 添加相应资源(tan 20110801)
		saveCiCategoryOperation(entity.getCname(), entity.getCno());
		dto.setCno(entity.getCno());
	}

	/**
	 * Remove CICategory
	 * 
	 * @param cno
	 * @return boolean
	 */
	@Transactional
	public boolean removeCICategory(Long cno) {
		boolean result = false;
		if (cno != null && cno != 0) {

			cicategoryDAO.deleteByIds(new Long[] { cno });

			// 删除相应资源(tan 20110801)
			Operation operation = operationDAO.findUniqueBy("resCode",
					"CONFIGUREITEMCATEGORY_RES" + cno);

			if (operation != null) {
				operationDAO.deleteByIds(new Long[] { operation.getResNo() });// 删除资源
			}

			result = true;
		}

		return result;
	}

	

	/**
	 * Update CICategory
	 * 
	 * @param dto
	 */
	@Transactional
	public void updateCICategory(CategoryDTO dto) {
		CICategory entity = cicategoryDAO.findById(dto.getCno());

		if (dto.getCname() != null) {
			entity.setCname(dto.getCname());
		}

		if (dto.getDescription() != null) {
			entity.setDescription(dto.getDescription());
		}

		if (dto.getIconPath() != null) {
			entity.setIconPath(dto.getIconPath());
		}
		entity.setFormId(dto.getFormId());
		entity.setCategoryType(dto.getCategoryType());
		entity.setCategoryCodeRule(dto.getCategoryCodeRule());
		if (entity.getParent() != null) {
			entity.setPath(entity.getParent().getPath() + entity.getCno() + "/");
			entity.setPathAlias(entity.getParent().getPathAlias() + entity.getCname() + "/");
		} else {
			entity.setPath(entity.getCno() + "/");
			entity.setPathAlias(entity.getPathAlias()+"/");
		}

		// 判断当前资源是否存在，if不存在添加，else更新
		Operation operation = operationDAO.findUniqueBy("resCode",
				"CONFIGUREITEMCATEGORY_RES" + entity.getCno());
		if (operation != null) {
			Byte dataFlag = 0;
			operation.setResName(entity.getCname());
			operation.setResCode("CONFIGUREITEMCATEGORY_RES" + entity.getCno());
			operation.setResUrl("CONFIGUREITEMCATEGORY_RES" + entity.getCno());
			operation.setDataFlag(dataFlag);
			operationDAO.update(operation);
		} else {
			OperationDTO operationDTO = new OperationDTO();
			operationDTO.setResName(entity.getCname());
			operationDTO.setResCode("CONFIGUREITEMCATEGORY_RES"
					+ entity.getCno());
			operationDTO.setResUrl("CONFIGUREITEMCATEGORY_RES"
					+ entity.getCno());
			operationDTO.setFunctionResCode("CONFIGUREITEMCATEGORY_RES");
			operationService.addOperation(operationDTO);
		}
	}

	/**
	 * Change CICategory
	 * 
	 * @param dto
	 */
	@Transactional
	public void changeCICategory(CategoryDTO dto) {

		CICategory entity = cicategoryDAO.findById(dto.getCno());
		CICategory parent = cicategoryDAO.findById(dto.getParentNo());

		// add mars---start
		List<Category> children = parent.getChildren();
		if (children == null) {
			children = new ArrayList<Category>();
		}
		children.add(entity);
		parent.setChildren(children);
		cicategoryDAO.save(parent);
		if (parent.getParent() != null) {
			parent.setPath(parent.getParent().getPath() + parent.getCno() + "/");
		} else {
			parent.setPath(parent.getCno() + "/");
		}
		// end

		entity.setParent(parent);
		cicategoryDAO.merge(entity);
		if (entity.getParent() != null) {
			entity.setPath(entity.getParent().getPath() + entity.getCno() + "/");
			entity.setPathAlias(entity.getParent().getPathAlias()+entity.getCname()+"/");
		} else {
			entity.setPath(entity.getCno() + "/");
			entity.setPathAlias(entity.getCname()+"/");
		}

	}

	/**
	 * setChild
	 * 
	 * @param parent
	 * @param child
	 */
	@Transactional
	private void setChild(CICategory parent, CICategory child) {

		// 有子
		if (child.getChildren() != null && child.getChildren().size() > 0) {

			for (Category c : child.getChildren()) {

				CICategory nc = new CICategory();

				nc.setCategoryType(c.getCategoryType());
				nc.setCname(c.getCname());
				nc.setIconPath(c.getIconPath());
				nc.setDescription(c.getDescription());
				nc.setCategoryCodeRule(c.getCategoryCodeRule());
				nc.setParent(parent);

				cicategoryDAO.save(nc);
				if (nc.getParent() != null) {
					nc.setPath(nc.getParent().getPath() + nc.getCno() + "/");
				} else {
					nc.setPath(nc.getCno() + "/");
				}
				setChild(nc, (CICategory) c);

			}

		}
	}

	/**
	 * copyCICategory
	 * 
	 * @param dto
	 */
	@Transactional
	public Long copyCICategory(CategoryDTO dto) {
		CICategory entity = cicategoryDAO.findById(dto.getCno());
		CICategory parent = cicategoryDAO.findById(dto.getParentNo());

		CICategory newChild = new CICategory();

		newChild.setCategoryType(entity.getCategoryType());
		newChild.setCname(entity.getCname());
		newChild.setIconPath(entity.getIconPath());
		newChild.setDescription(entity.getDescription());
		newChild.setCategoryCodeRule(entity.getCategoryCodeRule());

		newChild.setParent(parent);

		cicategoryDAO.save(newChild);
		if (newChild.getParent() != null) {
			newChild.setPath(newChild.getParent().getPath() + newChild.getCno()
					+ "/");
		} else {
			newChild.setPath(newChild.getCno() + "/");
		}
		setChild(newChild, entity);

		return newChild.getCno();

	}

	/**
	 * entity2dto Method
	 * 
	 * @param entity
	 * @param dto
	 * @param isAll
	 * @param userName
	 * @param categoryNos
	 * @param isSimpleDto
	 */

	@Transactional
	private void entity2dto(Category entity, CategoryTreeViewDTO dto,
			boolean isAll,Long[] categoryNos,
			boolean isSimpleDto) {
		try {
			entity2dto(entity, dto, isSimpleDto);
			// mars modify
			List<Category> childre = entity.getChildren();
			if (childre != null && childre.size() > 0) {
				for (Category ctg : childre) {
					if (isAll) {// 是否查询全部
						CategoryTreeViewDTO regDTO = new CategoryTreeViewDTO();
						entity2dto(ctg, regDTO, isSimpleDto);
						dto.getChildren().add(regDTO);
					} else {// 根据权限查询
						if (isListExist(ctg.getCno(), categoryNos)) {
							CategoryTreeViewDTO regDTO = new CategoryTreeViewDTO();
							entity2dto(ctg, regDTO, isSimpleDto);
							dto.getChildren().add(regDTO);
						}
					}
				}
			}
		} catch (Exception ex) {
			throw new ApplicationException(
					"Exception caused while converting Entity into DTO: "
							+ ex.getMessage(), ex);
		}

	}

	/**
	 * entity2dto Method
	 * 
	 * @param entity
	 * @param list
	 * @param isAll
	 * @param userName
	 * @param categoryNos
	 * @param isSimpleDto
	 */

	@Transactional
	private void entity2dtoSub(Category entity, List<CategoryTreeViewDTO> list,
			boolean isAll, Long[] categoryNos,
			boolean isSimpleDto) {
		try {
			// mars modify
			List<Category> childre = entity.getChildren();
			if (childre != null && childre.size() > 0) {
				for (Category ctg : childre) {
					if (isAll) {// 是否查询全部
						CategoryTreeViewDTO regDTO = new CategoryTreeViewDTO();
						entity2dto(ctg, regDTO, isSimpleDto);
						list.add(regDTO);
					} else {// 根据权限查询
						if (isListExist(ctg.getCno(), categoryNos)) {
							CategoryTreeViewDTO regDTO = new CategoryTreeViewDTO();
							entity2dto(ctg, regDTO, isSimpleDto);
							list.add(regDTO);
						}
					}
				}
			}

		} catch (Exception ex) {
			throw new ApplicationException(
					"Exception caused while converting Entity into DTO: "
							+ ex.getMessage(), ex);
		}

	}

	/**
	 * entity2dto Method
	 * 
	 * @param entity
	 * @param dto
	 * @param isSimpleDto
	 */
	@Transactional
	private void entity2dto(Category entity, CategoryTreeViewDTO dto,
			boolean isSimpleDto) {
		dto.setData(entity.getCname());
		dto.getAttr().put("cno", "" + entity.getCno());
		dto.getAttr().put("cname", entity.getCname());
		dto.getAttr().put("categoryCodeRule", entity.getCategoryCodeRule());
		if (entity.getCategoryType() != null) {
			dto.getAttr().put("categoryType",
					entity.getCategoryType().toString());
		}
		if (!isSimpleDto) {
			dto.getAttr().put("description", entity.getDescription());
			dto.getAttr().put("iconPath", entity.getIconPath());
			dto.getAttr().put("categoryRoot", entity.getCategoryRoot());

		}
		// mars modify
		List<Category> childre = entity.getChildren();
		// 如果当前节点是父节点或当前节点的父节点是根节点，那么状态默认Open
		if (childre != null && childre.size() > 0) {
			dto.setState("closed");
		}
		if (StringUtils.hasText(entity.getCategoryRoot())) {// 得到父节点标识
			dto.setState("open");
		}
		dto.getAttr().put("state", dto.getState());
	}

	/**
	 * 判断数组是否包含编号
	 * 
	 * @param eno
	 *            编号
	 * @param enos
	 *            数组
	 * @return boolean
	 */
	private boolean isListExist(Long eno, Long[] enos) {
		boolean result = false;
		if (enos != null && enos.length > 0 && eno != null) {
			for (Long no : enos) {
				if (eno.equals(no)) {
					result = true;
					break;
				}
			}
		}
		return result;
	}
	/**
	 * 获取配置基分类
	 * 
	 * @param dtype
	 * @return List<CICategory>
	 */
	@Transactional
	private List<CICategory> findCiCategory(String dtype) {
		List<CICategory> ciCategoryList = new ArrayList<CICategory>();
		List<CICategory> ciCategory = cicategoryDAO
				.findConfigurationItems(dtype);
		for (CICategory ec : ciCategory) {
			cycleSubCategory(ec, ciCategoryList);
		}
		return ciCategoryList;
	}

	/**
	 * 递归读取子分类
	 * 
	 * @param entity
	 * @param ciCategoryList
	 */

	private void cycleSubCategory(CICategory entity,
			List<CICategory> ciCategoryList) {

		if (entity.getDataFlag() != 99) {
			try {
				ciCategoryList.add(entity);
				if (entity.getChildren()!=null && !entity.getChildren().isEmpty()) {
					for (Category ecy : entity.getChildren()) {
						cycleSubCategory((CICategory) ecy, ciCategoryList);
					}
				}
			} catch (Exception ex) {
				throw new ApplicationException(
						"Exception caused while converting Entity into DTO: "
								+ ex.getMessage(), ex);
			}

		}
	}

	/**
	 * 导出数据方法
	 * 
	 * @throws Exception
	 */
	@Transactional
	public InputStream exportCiCategory(String dtype) {
		StringWriter sw = new StringWriter();
		CSVWriter csvw = new CSVWriter(sw);
		List<String[]> data = new ArrayList<String[]>();
		LanguageContent lc = LanguageContent.getInstance();
		data.add(new String[] { lc.getContent("common.id"),
				lc.getContent("label.categoryName"),
				lc.getContent("label.categoryDescription"),
				lc.getContent("common.extendedAttribute"),
				lc.getContent("title.resource.parentFunction"),
				lc.getContent("label.CategoryRoot") });
		List<CICategory> listEntity = findCiCategory(dtype);
		if (listEntity != null && listEntity.size() > 0) {
			for (CICategory item : listEntity) {
				String categoryType = "", parent = "";
				if (item.getCategoryType() != null && item.getCategoryType() != 0) {
					categoryType = cicategoryDAO.getFindEavEntity(item.getCategoryType().toString());
				}
				if (item.getParent() != null) {
					parent = item.getParent().getCname().toString();
				}
				data.add(new String[] { item.getCno().toString(),
						item.getCname(), item.getDescription(), categoryType,
						parent, item.getCategoryRoot() });
			}
		}
		csvw.writeAll(data);
		byte[] bs = null;
		try {
			bs = sw.getBuffer().toString().getBytes("GBK");
		} catch (UnsupportedEncodingException e1) {
			LOGGER.error(e1);
		}
		ByteArrayInputStream stream = null;
		if(bs!=null){
			stream = new ByteArrayInputStream(bs);
		}
		try {
			if (csvw != null) {
				csvw.flush();
				csvw.close();
			}
			if (sw != null) {
				sw.flush();
				sw.close();
			}
		} catch (IOException e) {
			LOGGER.error(e);
		}
		return stream;
	}

	/**
	 * 导入数据方法.
	 * 
	 * @param importFile
	 * @return String
	 */
	@Transactional
	public String importCiCategory(File importFile) {

		int insert = 0;
		int update = 0;
		int total = 0;
		int failure = 0;
		Reader rd = null;
		CSVReader reader = null;
		try {
			String fileEncode = FileEncodeUtils.getFileEncode(importFile);
			rd = new InputStreamReader(new FileInputStream(importFile), fileEncode);
			reader = new CSVReader(rd);
			String[] line = null;
			try {
				while ((line = reader.readNext()) != null) {

					CICategory ciCategory = new CICategory();
					if (StringUtils.hasText(line[0].toString())) {
						ciCategory.setCno(Long.parseLong(line[0]));
					}
					ciCategory.setCname(line[1]);
					ciCategory.setDescription(line[2]);
					if (StringUtils.hasText(line[3])) {
						ciCategory.setCategoryType(Long.parseLong(line[3]));
					}
					if (StringUtils.hasText(line[4])) {
						ciCategory.setParent(cicategoryDAO.findById(Long
								.parseLong(line[4])));
					}
					ciCategory.setCategoryRoot(line[5]);
					cicategoryDAO.save(ciCategory);
					if (ciCategory.getParent() != null) {
						ciCategory.setPath(ciCategory.getParent().getPath()
								+ ciCategory.getCno() + "/");
					} else {
						ciCategory.setPath(ciCategory.getCno() + "/");
					}
					// 添加相应资源(tan 20110801)
					saveCiCategoryOperation(ciCategory.getCname(),
							ciCategory.getCno());

					insert++;
					total++;
				}
				return "Total:" + total + ",&nbsp;Insert:" + insert
						+ ",&nbsp;Update:" + update + ",&nbsp;Failure:"
						+ failure;

			} catch (Exception e) {
				throw new ApplicationException("ERROR_CSV_FILE_NOT_EXISTS\n"
						+ e, e);
			}
		} catch (Exception ex) {
			throw new ApplicationException("ERROR_CSV_FILE_IO\n" + ex, ex);
		} finally {
			try {
				if (rd != null) {
					rd.close();
				}
				if (reader != null) {
					reader.close();
				}
			} catch (IOException e) {
				LOGGER.error(e);
			}
		}
	}

	/**
	 * 保存分类操作资源并赋值给系统管理员(默认角色)
	 * 
	 * @param cname
	 * @param cno
	 */
	@Transactional
	private void saveCiCategoryOperation(String cname, Long cno) {
		OperationDTO operationDTO = new OperationDTO();
		operationDTO.setResName(cname);
		operationDTO.setResCode("CONFIGUREITEMCATEGORY_RES" + cno);
		operationDTO.setResUrl("CONFIGUREITEMCATEGORY_RES" + cno);
		operationDTO.setFunctionResCode("CONFIGUREITEMCATEGORY_RES");
		operationService.addOperation(operationDTO);
		//把权限赋给所有角色
		Operation operation = operationDAO.findUniqueBy("resCode","CONFIGUREITEMCATEGORY_RES" + cno);
		List<Role> roles = roleDAO.findRolesByRoleCodes(new String[]{
				IRoleService.ROLE_SYSADMIN,
				IRoleService.ROLE_ITSOP_MANAGEMENT,
				IRoleService.ROLE_THIRDLINEENGINEER
		});
		for (Role role : roles) {
			if (role != null) {
				if(role.getResources()==null){
					role.setResources(new HashSet<Resource>());
				}
				role.getResources().add(operation);
				roleDAO.merge(role);
			}
		} 

	}

	/**
	 * 添加配置项分类查看功能.
	 */
	private void addCategoryFunction() {
		LanguageContent languageContent = LanguageContent.getInstance();

		// VAN 2011-08-05
		Function function = functionDAO.findUniqueBy("resCode",
				"CONFIGUREITEMCATEGORY_RES");// 功能不存在则添加一个
		if (function == null) {
			function = new Function();
			// 父节点
			function.setParentFunction(functionDAO.findUniqueBy("resCode",
					"CIM_MAIN"));
			function.setResName(languageContent
					.getContent("title.request.CICategory"));
			function.setResCode("CONFIGUREITEMCATEGORY_RES");
			function.setResUrl("CONFIGUREITEMCATEGORY_RES");
			functionDAO.save(function);
		}
	}

	/**
	 * 同步配置项分类和资源.
	 */
	@Transactional
	public void syncCICategory() {

		List<CICategory> categoryParents = cicategoryDAO
				.findConfigurationItems("CICategory");
		List<CICategory> allCategorys = cicategoryDAO
				.findConfigurationItems("CICategory");

		// 递归查找所有子节点
		if (categoryParents != null && categoryParents.size() > 0) {

			for (CICategory c : categoryParents) {
				cycleSubCategory(c, allCategorys);
			}

		}

		doSync(allCategorys);

	}

	/**
	 * 执行同步.
	 * 
	 * @param allCategorys
	 */
	private void doSync(List<CICategory> allCategorys) {
		// 同步所有分类
		if (allCategorys != null && allCategorys.size() > 0) {
			Role sysadminRole = roleDAO.findUniqueBy("roleCode",
				 IRoleService.ROLE_SYSADMIN);
			for (CICategory entity : allCategorys) {
				Operation operation = operationDAO.findUniqueBy("resCode",
						"CONFIGUREITEMCATEGORY_RES" + entity.getCno());
				if (operation != null) {
					Byte dataFlag = 0;
					operation.setResName(entity.getCname());
					operation.setResCode("CONFIGUREITEMCATEGORY_RES"
							+ entity.getCno());
					operation.setResUrl("CONFIGUREITEMCATEGORY_RES"
							+ entity.getCno());
					operation.setDataFlag(dataFlag);
					operationDAO.update(operation);
				} else {
					addCategoryFunction();
					OperationDTO operationDTO = new OperationDTO();
					operationDTO.setResName(entity.getCname());
					operationDTO.setResCode("CONFIGUREITEMCATEGORY_RES"
							+ entity.getCno());
					operationDTO.setResUrl("CONFIGUREITEMCATEGORY_RES"
							+ entity.getCno());
					operationDTO
							.setFunctionResCode("CONFIGUREITEMCATEGORY_RES");
					operationService.addOperation(operationDTO);
					if (sysadminRole != null) {
						sysadminRole.getResources().add(operation);
						roleDAO.merge(sysadminRole);
						Role role = roleDAO.findUniqueBy("roleCode",
								IRoleService.ROLE_SYSADMIN);
						if (role != null) {
							role.getResources().add(
									operationDAO.findUniqueBy("resCode",
											"CONFIGUREITEMCATEGORY_RES"
													+ entity.getCno()));
							roleDAO.merge(role);
						}
					}
				}
			}
		}

	}

	/**
	 * 递归查找子分类.
	 * 
	 * @param categoryId
	 */
	@Transactional
	public List<CategoryDTO> findSubCategorys(Long categoryId) {
		List<CategoryDTO> dtos = null;
		CICategory entity = cicategoryDAO.findById(categoryId);

		// 递归
		List<CICategory> categoryList = new ArrayList<CICategory>();

		cycleSubCategory(entity, categoryList);

		if (categoryList != null && categoryList.size() > 0) {
			dtos = new ArrayList<CategoryDTO>(categoryList.size() - 1);
			for (CICategory ct : categoryList) {
				if (!entity.equals(ct)) {
					CategoryDTO dto = new CategoryDTO();
					dto.setCno(ct.getCno());
					dto.setCname(ct.getCname());
					dtos.add(dto);
				}
			}
		}
		return dtos;
	}
	
	/**
	 * 递归查找子分类.
	 * 
	 * @param categoryId
	 */
	@Transactional
	public List<CategoryDTO> findSubCategorysByResType(Long categoryId) {
		List<CategoryDTO> dtos = null;
		CICategory entity = cicategoryDAO.findById(categoryId);
		Long[] categorys = userInfoService.findCategoryNosByLoginName(appctx.getCurrentLoginName(), "CONFIGUREITEMCATEGORY_RES");// 设置查看权限
		List<Long> cts =Arrays.asList(categorys);
		// 递归
		List<CICategory> categoryList = new ArrayList<CICategory>();
		cycleSubCategory(entity, categoryList);
		if (categoryList != null && categoryList.size() > 0) {
			dtos = new ArrayList<CategoryDTO>(categoryList.size() - 1);
			for (CICategory ct : categoryList) {
				if (!entity.equals(ct)&&cts.contains(ct.getCno())) {
					CategoryDTO dto = new CategoryDTO();
					dto.setCno(ct.getCno());
					dto.setCname(ct.getCname());
					dtos.add(dto);
				}
			}
		}
		return dtos;
	}

	/**
	 * 递归查找子分类.数组
	 * 
	 * @param categoryId
	 */
	@Transactional
	public List<CategoryDTO> findSubCategorysArray(Long[] categoryId) {
		List<CategoryDTO> dtos = new ArrayList<CategoryDTO>();

		for (int k = 0; k < categoryId.length; k++) {
			CICategory entity = cicategoryDAO.findById(categoryId[k]);
			// 递归
			List<CICategory> categoryList = new ArrayList<CICategory>();
			cycleSubCategory(entity, categoryList);
			if (categoryList != null) {
				for (CICategory ct : categoryList) {
					CategoryDTO dto = new CategoryDTO();
					dto.setCno(ct.getCno());
					dto.setCname(ct.getCname());
					dtos.add(dto);
				}
			}
		}

		return dtos;
	}

	/**
	 * 对全部的分类进行Path更新
	 */
	private void updateAllCategoryPath() {
		List<CICategory> ciCategoryList = cicategoryDAO.findAll();
		for (CICategory entity : ciCategoryList) {
			if (entity.getParent() != null) {
				entity.setPath(entity.getParent().getPath() + entity.getCno()+ "/");
				entity.setPathAlias(entity.getParent().getPathAlias() + entity.getCname()+ "/");
			} else {
				entity.setPath(entity.getCno() + "/");
				entity.setPathAlias(entity.getCname() + "/");
			}
		}
	}

	/**
	 * 根据ID查询分类
	 */
	public Long findCategoryId(Long cno) {
		Long categourType=null;
		CICategory ciCategory=cicategoryDAO.findById(cno);
		if(ciCategory.getCategoryType()!=null){
			categourType=ciCategory.getCategoryType();
		}
		return categourType;
	}
	/**
     * 根据指定的分类id查询分类及父分类名称，如：配置项分类-桌面系统；“-”是默认分隔符
     * @param categoryId
     * @return
     */
	@Transactional
	public String findCategoryNameIncludParent(CICategory ciCategory,Long categoryId) {
		//分类名（默认为根目录名称）
		String val = LanguageContent.getInstance().getContent("title.request.CICategory");
		if(ciCategory == null && categoryId != null){
			ciCategory=cicategoryDAO.findById(categoryId);
		}
		if( ciCategory != null){
			String[] idStrs = null;
			if(ciCategory.getPath() != null 
					&& (idStrs = ciCategory.getPath().split("/")).length > 1 ){
				Long[] ids = new Long[idStrs.length];
				for (int i = 0; i < idStrs.length; i++) {
					ids[i] = Long.parseLong(idStrs[i]);
				}
				List<CICategory> cis=cicategoryDAO.findByIds(ids);
				int size = 0;
				if( cis != null && (size = cis.size()) > 0){
					StringBuffer buff = new StringBuffer();
					for (int i = 0; i < size; i++) {
						buff.append(cis.get(i).getCname());
						buff.append(DEFAULT_SEPARATOR);
					}
					val = buff.substring(0, buff.length()-1).toString();
				}
			}
			if( val.length() == 0){
				val = ciCategory.getCname();
			}
		}
		return val;
	}
	@Transactional
	public void deleteEavEntity(Long[] eavNos){
		List<CICategory> cis=cicategoryDAO.findEavEntity(eavNos);
		for(CICategory ci:cis){
			ci.setCategoryType(null);
		}
	}

}
